﻿using LittleBee.EngUnit;
using LittleBee.Utils;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;

namespace LittleBee.Cells
{
	public abstract class Pointer : INotifyPointerPropertyChanged, INotifyPointerPropertyChanging
	{
		/// <summary>
		/// the attribute of pointer
		/// </summary>
		public enum Attributes
		{
			Default = Temporary,

			Input = 0x00000001,
			Output = 0x000000002,
			Parameter = 0x00000004,

			DataPacket = 0x00000010,
			Temporary = 0x00000020, //后台仅用于计算和存储的中间量，不会被传送给web
			ReadOnly = 0x00000040,

			MaxValue = 0x00000100,
			MinValue = 0x00000200,
			EngUnit = 0x00000400,

			Array = 0x00001000,
			Struct = 0x00002000,
			Map = 0x00004000,
			Polymorphic = 0x00008000,
		}

		/// <summary>
		/// pointer properties list
		/// </summary>
		public const string PID = "pid";
		public const string DESC = "desc";
		public const string NAME = "name";
		public const string ATTR = "attr";
		//private const string PHELP = "helper";
		public const string MAX = "max";
		public const string MIN = "min";
		public const string SIZE = "size";
		public const string DEF = "def";
		public const string PREC = "prec";
		public const string VT = "vt";
		public const string EU = "eu";
		public const string VAL = "val";
		public const string VALUE = "value";
		public const string ATTRIBUTE = "attribute";
		public const string REF = "ref";

		/// <summary>
		/// pointer data type
		/// </summary>
		public const string VT_SBYTE = "sbyte";
		public const string VT_SHORT = "short";
		public const string VT_INT = "int";
		public const string VT_LONG = "long";
		public const string VT_BYTE = "byte";
		public const string VT_USHORT = "ushort";
		public const string VT_UINT = "uint";
		public const string VT_ULONG = "ulong";
		public const string VT_DECIMAL = "decimal";
		public const string VT_FLOAT = "float";
		public const string VT_DOUBLE = "double";
		public const string VT_STRING = "string";
		public const string VT_BOOL = "bool";
		public const string VT_BIN = "binary";
		public const string VT_LIST = "list";
		public const string VT_MAP = "map";
		public const string VT_DATETIME = "datetime";
		public const string VT_TIMESPAN = "timespan";
		public const string VT_EU = "eu";
		public const string VT_POINTER = "pointer";

		public abstract event PointerPropertyChangedEventHandler PointerPropertyChanged;
		public abstract event PointerPropertyChangingEventHandler PointerPropertyChanging;

		//		public delegate bool PointerPropertyChangingEventHandler(object sender, PointerPropertyChangingEventArgs e);
		//		public delegate bool PointerPropertyChangedEventHandler(object sender, PointerPropertyChangedEventArgs e);
		//		public abstract event PointerPropertyChangedEventHandler PointerPropertyChanged;
		//		public abstract event PropertyChangingEventHandler PropertyChanging;

		public Pointer SetValue(JObject x)
		{
			return _arrSetPointerValueJObjectOps[(int)this.PointerTypeID](this, x);
		}
		public virtual Pointer SetValue<T>(T x)
		{
			return _arrSetPointerValueStringOps[(int)this.PointerTypeID](this, x!);
		}

		public abstract JObject JValue { get; }
		public abstract T Value<T>();
		public override string ToString() { return _arrToStringOps[(int)PointerTypeID](this); }

		public string this[int idx]
		{
			get
			{
				if ((Attr & Pointer.Attributes.Array) == Pointer.Attributes.Array)
				{
					return (JValue[VAL]![idx])!.ToString(Formatting.None);
				}
				throw new InvalidOperationException($"Not valid array pointer type");
			}
		}
		public string this[string key]
		{
			get
			{
				if ((Attr & Pointer.Attributes.Map) == Pointer.Attributes.Map)
				{
					return JValue[VAL]![key]!.ToString(Formatting.None);
				}
				else if ((Attr & Pointer.Attributes.Struct) == Pointer.Attributes.Struct)
				{
					return JValue[VAL]![key]!.ToString(Formatting.None);
				}
				throw new InvalidOperationException($"Not valid array pointer type");
			}
		}

		protected abstract TypeID PointerTypeID { get; set; }

		private const Pointer.Attributes @default = Pointer.Attributes.Default;

		public static Pointer Create(string pid, string name, string desc, Pointer.Attributes attr, string pvt, JObject joVal, JObject joHelper)
		{
			if ((attr & (Pointer.Attributes.Map | Pointer.Attributes.Array | Pointer.Attributes.Struct)) != 0)
			{
				if ((attr & Pointer.Attributes.Map) == Pointer.Attributes.Map)
				{
					switch (pvt)
					{
						case Pointer.VT_BOOL:
							return new Pointer<Dictionary<string, bool>>(joVal, joHelper, pid, name, desc, attr);
						case Pointer.VT_INT:
							return new Pointer<Dictionary<string, int>>(joVal, joHelper, pid, name, desc, attr);
						case Pointer.VT_DOUBLE:
							return new Pointer<Dictionary<string, double>>(joVal, joHelper, pid, name, desc, attr);
						case Pointer.VT_STRING:
							return new Pointer<Dictionary<string, string>>(joVal, joHelper, pid, name, desc, attr);
						case Pointer.VT_BIN:
							return new Pointer<Dictionary<string, byte[]>>(joVal, joHelper, pid, name, desc, attr);
						case Pointer.VT_DATETIME:
							return new Pointer<Dictionary<string, DateTime>>(joVal, joHelper, pid, name, desc, attr);
						case Pointer.VT_TIMESPAN:
							return new Pointer<Dictionary<string, TimeSpan>>(joVal, joHelper, pid, name, desc, attr);
						case Pointer.VT_EU:
							return new Pointer<Dictionary<string, EUValue>>(joVal, joHelper, pid, name, desc, attr);
						default:
							throw new ArgumentException($"Unsupported Pointer Type: {pvt}");
					}
				}
				else if ((attr & Pointer.Attributes.Array) == Pointer.Attributes.Array)
				{
					switch (pvt)
					{
						case Pointer.VT_BOOL:
							return new Pointer<List<bool>>(joVal, joHelper, pid, name, desc, attr);
						case Pointer.VT_INT:
							return new Pointer<List<int>>(joVal, joHelper, pid, name, desc, attr);
						case Pointer.VT_DOUBLE:
							return new Pointer<List<double>>(joVal, joHelper, pid, name, desc, attr);
						case Pointer.VT_STRING:
							return new Pointer<List<string>>(joVal, joHelper, pid, name, desc, attr);
						case Pointer.VT_BIN:
							return new Pointer<List<byte[]>>(joVal, joHelper, pid, name, desc, attr);
						case Pointer.VT_DATETIME:
							return new Pointer<List<DateTime>>(joVal, joHelper, pid, name, desc, attr);
						case Pointer.VT_TIMESPAN:
							return new Pointer<List<TimeSpan>>(joVal, joHelper, pid, name, desc, attr);
						case Pointer.VT_EU:
							return new Pointer<List<EUValue>>(joVal, joHelper, pid, name, desc, attr);
						default:
							throw new ArgumentException($"Unsupported Pointer Type: {pvt}");
					}
				}
				else if ((attr & Pointer.Attributes.Struct) == Pointer.Attributes.Struct)
				{
					throw new ArgumentException($"Unsupported Pointer Type: {pvt}");
				}
				else
				{
					throw new ArgumentException($"Unsupported Pointer Type: {pvt}");
				}
 			}
			else
			{
				switch (pvt)
				{
					case Pointer.VT_INT:
						return new Pointer<int>(joVal, joHelper, pid, name, desc, attr);
					case Pointer.VT_UINT:
						return new Pointer<uint>(joVal, joHelper, pid, name, desc, attr);
					case Pointer.VT_LONG:
						return new Pointer<long>(joVal, joHelper, pid, name, desc, attr);
					case Pointer.VT_ULONG:
						return new Pointer<ulong>(joVal, joHelper, pid, name, desc, attr);
					case Pointer.VT_DECIMAL:
						return new Pointer<decimal>(joVal, joHelper, pid, name, desc, attr);
					case Pointer.VT_FLOAT:
						return new Pointer<float>(joVal, joHelper, pid, name, desc, attr);
					case Pointer.VT_DOUBLE:
						return new Pointer<double>(joVal, joHelper, pid, name, desc, attr);
					case Pointer.VT_BOOL:
						return new Pointer<bool>(joVal, joHelper, pid, name, desc, attr);
					case Pointer.VT_STRING:
						return new Pointer<string>(joVal, joHelper, pid, name, desc, attr);
					case Pointer.VT_BIN:
						return new Pointer<byte[]>(joVal, joHelper, pid, name, desc, attr);
					case Pointer.VT_DATETIME:
						return new Pointer<DateTimeOffset>(joVal, joHelper, pid, name, desc, attr);
					case Pointer.VT_TIMESPAN:
						return new Pointer<TimeSpan>(joVal, joHelper, pid, name, desc, attr);
					case Pointer.VT_EU:
						return new Pointer<EUValue>(joVal, joHelper, pid, name, desc, attr);
					default:
						throw new ArgumentException($"Unsupported Pointer Type: {pvt}");
				}
			}
		}

		public Pointer(string pid = "", string name = "", string desc = "", Pointer.Attributes attr = @default)
		{
			Pid = pid;
			Name = name;
			Description = desc;
			Attr = attr;
		}

		protected enum TypeID
		{
			PTI_BOOL,
			PTI_SBYTE,
			PTI_SHORT,
			PTI_INT,
			PTI_LONG,
			PTI_BYTE,
			PTI_USHORT,
			PTI_UINT,
			PTI_ULONG,
			PTI_DECIMAL,
			PTI_FLOAT,
			PTI_DOUBLE,
			PTI_STRING,
			PTI_BIN,
			PTI_DATETIME,
			PTI_TIMESPAN,
			PTI_EU,
			PTI_LIST,
			PTI_MAP,
			PTI_COUNT
		}

		protected static Dictionary<string, TypeID> _dctPoiterType2ID = new Dictionary<string, TypeID>()
		{
			{ Pointer.VT_BOOL, TypeID.PTI_BOOL },
			{ Pointer.VT_SBYTE, TypeID.PTI_SBYTE },
			{ Pointer.VT_SHORT, TypeID.PTI_SHORT },
			{ Pointer.VT_INT, TypeID.PTI_INT },
			{ Pointer.VT_LONG, TypeID.PTI_LONG },
			{ Pointer.VT_BYTE, TypeID.PTI_BYTE },
			{ Pointer.VT_USHORT, TypeID.PTI_USHORT },
			{ Pointer.VT_UINT, TypeID.PTI_UINT },
			{ Pointer.VT_ULONG, TypeID.PTI_ULONG },
			{ Pointer.VT_DECIMAL, TypeID.PTI_DECIMAL },
			{ Pointer.VT_FLOAT, TypeID.PTI_FLOAT },
			{ Pointer.VT_DOUBLE, TypeID.PTI_DOUBLE },
			{ Pointer.VT_STRING, TypeID.PTI_STRING },
			{ Pointer.VT_BIN, TypeID.PTI_BIN },
			{ Pointer.VT_DATETIME, TypeID.PTI_DATETIME },
			{ Pointer.VT_TIMESPAN, TypeID.PTI_TIMESPAN },
			{ Pointer.VT_EU, TypeID.PTI_EU },
			{ Pointer.VT_LIST, TypeID.PTI_LIST },
			{ Pointer.VT_MAP, TypeID.PTI_MAP },
		};

		protected static Dictionary<Type, TypeID> _dctType2ID = new Dictionary<Type, TypeID>()
		{
			{ typeof(bool), TypeID.PTI_BOOL },
			{ typeof(sbyte), TypeID.PTI_SBYTE },
			{ typeof(short), TypeID.PTI_SHORT },
			{ typeof(int), TypeID.PTI_INT },
			{ typeof(long), TypeID.PTI_LONG },
			{ typeof(byte), TypeID.PTI_BYTE },
			{ typeof(ushort), TypeID.PTI_USHORT },
			{ typeof(uint), TypeID.PTI_UINT },
			{ typeof(ulong), TypeID.PTI_ULONG },
			{ typeof(decimal), TypeID.PTI_DECIMAL },
			{ typeof(float), TypeID.PTI_FLOAT },
			{ typeof(double), TypeID.PTI_DOUBLE },
			{ typeof(string), TypeID.PTI_STRING },
			{ typeof(byte[]), TypeID.PTI_BIN },
			{ typeof(DateTime), TypeID.PTI_DATETIME },
			{ typeof(TimeSpan), TypeID.PTI_TIMESPAN },
			{ typeof(EUValue), TypeID.PTI_EU },
			{ typeof(List<bool>), TypeID.PTI_LIST },
			{ typeof(List<sbyte>), TypeID.PTI_LIST },
			{ typeof(List<short>), TypeID.PTI_LIST },
			{ typeof(List<int>), TypeID.PTI_LIST },
			{ typeof(List<long>), TypeID.PTI_LIST },
			{ typeof(List<byte>), TypeID.PTI_LIST },
			{ typeof(List<ushort>), TypeID.PTI_LIST },
			{ typeof(List<uint>), TypeID.PTI_LIST },
			{ typeof(List<ulong>), TypeID.PTI_LIST },
			{ typeof(List<decimal>), TypeID.PTI_LIST },
			{ typeof(List<float>), TypeID.PTI_LIST },
			{ typeof(List<double>), TypeID.PTI_LIST },
			{ typeof(List<string>), TypeID.PTI_LIST },
			{ typeof(List<byte[]>), TypeID.PTI_LIST },
			{ typeof(List<DateTime>), TypeID.PTI_LIST },
			{ typeof(List<TimeSpan>), TypeID.PTI_LIST },
			{ typeof(List<EUValue>), TypeID.PTI_LIST },
			{ typeof(Dictionary<string, bool>), TypeID.PTI_MAP },
			{ typeof(Dictionary<string, sbyte>), TypeID.PTI_MAP },
			{ typeof(Dictionary<string, short>), TypeID.PTI_MAP },
			{ typeof(Dictionary<string, int>), TypeID.PTI_MAP },
			{ typeof(Dictionary<string, long>), TypeID.PTI_MAP },
			{ typeof(Dictionary<string, byte>), TypeID.PTI_MAP },
			{ typeof(Dictionary<string, ushort>), TypeID.PTI_MAP },
			{ typeof(Dictionary<string, uint>), TypeID.PTI_MAP },
			{ typeof(Dictionary<string, ulong>), TypeID.PTI_MAP },
			{ typeof(Dictionary<string, decimal>), TypeID.PTI_MAP },
			{ typeof(Dictionary<string, float>), TypeID.PTI_MAP },
			{ typeof(Dictionary<string, double>), TypeID.PTI_MAP },
			{ typeof(Dictionary<string, string>), TypeID.PTI_MAP },
			{ typeof(Dictionary<string, byte[]>), TypeID.PTI_MAP },
			{ typeof(Dictionary<string, DateTime>), TypeID.PTI_MAP },
			{ typeof(Dictionary<string, TimeSpan>), TypeID.PTI_MAP },
			{ typeof(Dictionary<string, EUValue>), TypeID.PTI_MAP },
		};

		protected static Dictionary<Type, Func<dynamic>> _dctPointerType2MakeDefValue = new Dictionary<Type, Func<dynamic>>
		{
			{ typeof(bool), () => { return default(bool); } },
			{ typeof(sbyte), () => { return default(sbyte); } },
			{ typeof(short), () => { return default(short); } },
			{ typeof(int), () => { return default(int); } },
			{ typeof(long), () => { return default(long); } },
			{ typeof(byte), () => { return default(byte); } },
			{ typeof(ushort), () => { return default(ushort); } },
			{ typeof(uint), () => { return default(uint); } },
			{ typeof(ulong), () => { return default(ulong); } },
			{ typeof(decimal), () => { return default(decimal); } },
			{ typeof(float), () => { return default(float); } },
			{ typeof(double), () => { return default(double); } },
			{ typeof(string), () => { return default(string)!; } },
			{ typeof(byte[]), () => { return default(byte[])!; } },
			{ typeof(DateTime), () => { return default(DateTime); } },
			{ typeof(TimeSpan), () => { return default(TimeSpan); } },
			{ typeof(EUValue), () => { return default(EUValue)!; } },
			{ typeof(List<bool>), () => { return new List<bool>(); } },
			{ typeof(List<sbyte>), () => { return new List<sbyte>(); } },
			{ typeof(List<short>), () => { return new List<short>(); } },
			{ typeof(List<int>), () => { return new List<int>(); } },
			{ typeof(List<long>), () => { return new List<long>(); } },
			{ typeof(List<byte>), () => { return new List<byte>(); } },
			{ typeof(List<ushort>), () => { return new List<ushort>(); } },
			{ typeof(List<uint>), () => { return new List<uint>(); } },
			{ typeof(List<ulong>), () => { return new List<ulong>(); } },
			{ typeof(List<decimal>), () => { return new List<decimal>(); } },
			{ typeof(List<float>), () => { return new List<float>(); } },
			{ typeof(List<double>), () => { return new List<double>(); } },
			{ typeof(List<string>), () => { return new List<string>(); } },
			{ typeof(List<byte[]>), () => { return new List<byte[]>(); } },
			{ typeof(List<DateTime>), () => { return new List<DateTime>(); } },
			{ typeof(List<TimeSpan>), () => { return new List<TimeSpan>(); } },
			{ typeof(List<EUValue>), () => { return new List<EUValue>(); } },
			{ typeof(Dictionary<string, bool>), () => { return new Dictionary<string, bool>(); } },
			{ typeof(Dictionary<string, sbyte>), () => { return new Dictionary<string, sbyte>(); } },
			{ typeof(Dictionary<string, short>), () => { return new Dictionary<string, short>(); } },
			{ typeof(Dictionary<string, int>), () => { return new Dictionary<string, int>(); } },
			{ typeof(Dictionary<string, long>), () => { return new Dictionary<string, long>(); } },
			{ typeof(Dictionary<string, byte>), () => { return new Dictionary<string, byte>(); } },
			{ typeof(Dictionary<string, ushort>), () => { return new Dictionary<string, ushort>(); } },
			{ typeof(Dictionary<string, uint>), () => { return new Dictionary<string, uint>(); } },
			{ typeof(Dictionary<string, ulong>), () => { return new Dictionary<string, ulong>(); } },
			{ typeof(Dictionary<string, decimal>), () => { return new Dictionary<string, decimal>(); } },
			{ typeof(Dictionary<string, float>), () => { return new Dictionary<string, float>(); } },
			{ typeof(Dictionary<string, double>), () => { return new Dictionary<string, double>(); } },
			{ typeof(Dictionary<string, string>), () => { return new Dictionary<string, string>(); } },
			{ typeof(Dictionary<string, byte[]>), () => { return new Dictionary<string, byte[]>(); } },
			{ typeof(Dictionary<string, DateTime>), () => { return new Dictionary<string, DateTime>(); } },
			{ typeof(Dictionary<string, TimeSpan>), () => { return new Dictionary<string, TimeSpan>(); } },
			{ typeof(Dictionary<string, EUValue>), () => { return new Dictionary<string, EUValue>(); } },
		};

		protected static Dictionary<Type, Func<JToken, dynamic>> _dctPointerType2MakeValue = new Dictionary<Type, Func<JToken, dynamic>>
		{
			{ typeof(bool), (v) => { return (bool)v; } },
			{ typeof(sbyte), (v) => { return (sbyte)v; } },
			{ typeof(short), (v) => { return (short)v; } },
			{ typeof(int), (v) => { return (int)v; } },
			{ typeof(long), (v) => { return (long)v; } },
			{ typeof(byte), (v) => { return (byte)v; } },
			{ typeof(ushort), (v) => { return (ushort)v; } },
			{ typeof(uint), (v) => { return (uint)v; } },
			{ typeof(ulong), (v) => { return (ulong)v; } },
			{ typeof(decimal), (v) => { return (decimal)v; } },
			{ typeof(float), (v) => { return (float)v; } },
			{ typeof(double), (v) => { return (double)v; } },
			{ typeof(string), (v) => { return (string)v!; } },
			{ typeof(byte[]), (v) => { return Encoding.UTF8.GetBytes((string)v!); } },
			{ typeof(DateTime), (v) => { return DateTime.Parse((string)v!); } },
			{ typeof(TimeSpan), (v) => { return TimeSpan.Parse((string)v!); } },
			{ typeof(EUValue), (v) => { return EUValue.Parse((string)v!); } },
			{ typeof(List<bool>), (v) => { var val = new List<bool>(); foreach (var x in (v as JArray)!.Values<bool>()) val.Add(x); return val; } },
			{ typeof(List<sbyte>), (v) => { var val = new List<sbyte>(); foreach (var x in (v as JArray)!.Values<sbyte>()) val.Add(x); return val; } },
			{ typeof(List<short>), (v) => { var val = new List<short>(); foreach (var x in (v as JArray)!.Values<short>()) val.Add(x); return val; } },
			{ typeof(List<int>), (v) => { var val = new List<int>(); foreach (var x in (v as JArray)!.Values<int>()) val.Add(x); return val; } },
			{ typeof(List<long>), (v) => { var val = new List<long>(); foreach (var x in (v as JArray)!.Values<long>()) val.Add(x); return val; } },
			{ typeof(List<byte>), (v) => { var val = new List<byte>(); foreach (var x in (v as JArray)!.Values<byte>()) val.Add(x); return val; } },
			{ typeof(List<ushort>), (v) => { var val = new List<ushort>(); foreach (var x in (v as JArray)!.Values<ushort>()) val.Add(x); return val; } },
			{ typeof(List<uint>), (v) => { var val = new List<uint>(); foreach (var x in (v as JArray)!.Values<uint>()) val.Add(x); return val; } },
			{ typeof(List<ulong>), (v) => { var val = new List<ulong>(); foreach (var x in (v as JArray)!.Values<ulong>()) val.Add(x); return val; } },
			{ typeof(List<decimal>), (v) => { var val = new List<decimal>(); foreach (var x in (v as JArray)!.Values<decimal>()) val.Add(x); return val; } },
			{ typeof(List<float>), (v) => { var val = new List<float>(); foreach (var x in (v as JArray)!.Values<float>()) val.Add(x); return val; } },
			{ typeof(List<double>), (v) => { var val = new List<double>(); foreach (var x in (v as JArray)!.Values<double>()) val.Add(x); return val; } },
			{ typeof(List<string>), (v) => { var val = new List<string>(); foreach (var x in (v as JArray)!.Values<string>()) val.Add(x!); return val; } },
			{ typeof(List<byte[]>), (v) => { var val = new List<byte[]>(); foreach (var x in (v as JArray)!.Values<string>()) val.Add(Encoding.UTF8.GetBytes(x!)); return val; } },
			{ typeof(List<DateTime>), (v) => { var val = new List<DateTime>(); foreach (var x in (v as JArray)!.Values<string>()) val.Add(DateTime.Parse(x!)); return val; } },
			{ typeof(List<TimeSpan>), (v) => { var val = new List<TimeSpan>(); foreach (var x in (v as JArray)!.Values<string>()) val.Add(TimeSpan.Parse(x!)); return val; } },
			{ typeof(List<EUValue>), (v) => { var val = new List<EUValue>(); foreach (var x in (v as JArray)!.Values<string>()) val.Add(EUValue.Parse(x!)); return val; } },
			{ typeof(Dictionary<string, bool>), (v) => { var val = new Dictionary<string, bool>(); foreach (var x in (v as JObject)!) val.Add(x.Key, (bool)x.Value!); return val; } },
			{ typeof(Dictionary<string, sbyte>), (v) => { var val = new Dictionary<string, sbyte>(); foreach (var x in (v as JObject)!) val.Add(x.Key, (sbyte)x.Value!); return val; } } ,
			{ typeof(Dictionary<string, short>), (v) => { var val = new Dictionary<string, short>(); foreach (var x in (v as JObject)!) val.Add(x.Key, (short)x.Value!); return val; } } ,
			{ typeof(Dictionary<string, int>), (v) => { var val = new Dictionary<string, int>(); foreach (var x in (v as JObject)!) val.Add(x.Key, (int)x.Value!); return val; } } ,
			{ typeof(Dictionary<string, long>), (v) => { var val = new Dictionary<string, long>(); foreach (var x in (v as JObject)!) val.Add(x.Key, (long)x.Value!); return val; } },
			{ typeof(Dictionary<string, byte>), (v) => { var val = new Dictionary<string, byte>(); foreach (var x in (v as JObject)!) val.Add(x.Key, (byte)x.Value!); return val; }  },
			{ typeof(Dictionary<string, ushort>), (v) => { var val = new Dictionary<string, ushort>(); foreach (var x in (v as JObject)!) val.Add(x.Key, (ushort)x.Value!); return val; } } ,
			{ typeof(Dictionary<string, uint>), (v) => { var val = new Dictionary<string, uint>(); foreach (var x in (v as JObject)!) val.Add(x.Key, (uint)x.Value!); return val; } } ,
			{ typeof(Dictionary<string, ulong>), (v) => { var val = new Dictionary<string, ulong>(); foreach (var x in (v as JObject)!) val.Add(x.Key, (ulong)x.Value!); return val; } },
			{ typeof(Dictionary<string, decimal>), (v) => { var val = new Dictionary<string, decimal>(); foreach (var x in (v as JObject)!) val.Add(x.Key, (decimal)x.Value!); return val; } },
			{ typeof(Dictionary<string, float>), (v) => { var val = new Dictionary<string, float>(); foreach (var x in (v as JObject)!) val.Add(x.Key, (float)x.Value!); return val; } },
			{ typeof(Dictionary<string, double>), (v) => { var val = new Dictionary<string, double>(); foreach (var x in (v as JObject)!) val.Add(x.Key, (double)x.Value!); return val; } },
			{ typeof(Dictionary<string, string>), (v) => { var val = new Dictionary<string, string>(); foreach (var x in (v as JObject)!) val.Add(x.Key, (string)x.Value!); return val; } },
			{ typeof(Dictionary<string, byte[]>), (v) => { var val = new Dictionary<string, byte[]>(); foreach (var x in (v as JObject)!) val.Add(x.Key, Encoding.UTF8.GetBytes((string)x.Value!)); return val; } },
			{ typeof(Dictionary<string, DateTime>), (v) => { var val = new Dictionary<string, DateTime>(); foreach (var x in (v as JObject)!) val.Add(x.Key, DateTime.Parse((string)x.Value!)); return val; } },
			{ typeof(Dictionary<string, TimeSpan>), (v) => { var val = new Dictionary<string, TimeSpan>(); foreach (var x in (v as JObject)!) val.Add(x.Key, TimeSpan.Parse((string)x.Value!)); return val; } },
			{ typeof(Dictionary<string, EUValue>), (v) => { var val = new Dictionary<string, EUValue>(); foreach (var x in (v as JObject)!) val.Add(x.Key, EUValue.Parse((string)x.Value!)); return val; } },
		};

		protected static Func<Pointer, Pointer, Pointer>[,] _arrTypeID2PointeTypeOp = new Func<Pointer, Pointer, Pointer>[(int)TypeID.PTI_COUNT, 4]
		{
			{	//Pointer.VT_BOOL
				(x,y)=>{ return x + y.Value<bool>(); },	// bool operator and
				(x,y)=>{ return x - y.Value<bool>(); },	// bool operator or
				(x,y)=>{ throw new NotSupportedException($"Not Supported operator: {x.Type} * {y.Type}"); },
				(x,y)=>{ throw new NotSupportedException($"Not Supported operator: {x.Type} / {y.Type}"); }
			},
			{	//Pointer.VT_SBYTE
				(x,y)=>{ return x + y.Value<sbyte>(); },
				(x,y)=>{ return x - y.Value<sbyte>(); },
				(x,y)=>{ return x * y.Value<sbyte>(); },
				(x,y)=>{ return x / y.Value<sbyte>(); }
			},
			{	//Pointer.VT_SHORT
				(x,y)=>{ return x + y.Value<short>(); },
				(x,y)=>{ return x - y.Value<short>(); },
				(x,y)=>{ return x * y.Value<short>(); },
				(x,y)=>{ return x / y.Value<short>(); }
			},
			{	//Pointer.VT_INT
				(x,y)=>{ return x + y.Value<int>(); },
				(x,y)=>{ return x - y.Value<int>(); },
				(x,y)=>{ return x * y.Value<int>(); },
				(x,y)=>{ return x / y.Value<int>(); }
			},
			{	//Pointer.VT_LONG
				(x,y)=>{ return x + y.Value<long>(); },
				(x,y)=>{ return x - y.Value<long>(); },
				(x,y)=>{ return x * y.Value<long>(); },
				(x,y)=>{ return x / y.Value<long>(); }
			},
			{	//Pointer.VT_BYTE
				(x,y)=>{ return x + y.Value<byte>(); },
				(x,y)=>{ return x - y.Value<byte>(); },
				(x,y)=>{ return x * y.Value<byte>(); },
				(x,y)=>{ return x / y.Value<byte>(); }
			},
			{	//Pointer.VT_USHORT
				(x,y)=>{ return x + y.Value<ushort>(); },
				(x,y)=>{ return x - y.Value<ushort>(); },
				(x,y)=>{ return x * y.Value<ushort>(); },
				(x,y)=>{ return x / y.Value<ushort>(); }
			},
			{	//Pointer.VT_UINT
				(x,y)=>{ return x + y.Value<uint>(); },
				(x,y)=>{ return x - y.Value<uint>(); },
				(x,y)=>{ return x * y.Value<uint>(); },
				(x,y)=>{ return x / y.Value<uint>(); }
			},
			{	//Pointer.VT_ULONG
				(x,y)=>{ return x + y.Value<ulong>(); },
				(x,y)=>{ return x - y.Value<ulong>(); },
				(x,y)=>{ return x * y.Value<ulong>(); },
				(x,y)=>{ return x / y.Value<ulong>(); }
			},
			{	//Pointer.VT_DECIMAL
				(x,y)=>{ return x + y.Value<decimal>(); },
				(x,y)=>{ return x - y.Value<decimal>(); },
				(x,y)=>{ return x * y.Value<decimal>(); },
				(x,y)=>{ return x / y.Value<decimal>(); }
			},
			{	//Pointer.VT_FLOAT
				(x,y)=>{ return x + y.Value<float>(); },
				(x,y)=>{ return x - y.Value<float>(); },
				(x,y)=>{ return x * y.Value<float>(); },
				(x,y)=>{ return x / y.Value<float>(); }
			},
			{	//Pointer.VT_DOUBLE
				(x,y)=>{ return x + y.Value<double>(); },
				(x,y)=>{ return x - y.Value<double>(); },
				(x,y)=>{ return x * y.Value<double>(); },
				(x,y)=>{ return x / y.Value<double>(); }
			},
			{	//Pointer.VT_STRING
				(x,y)=>{ return x + y.Value<string>(); },
				(x,y)=>{ throw new NotSupportedException($"Not Supported operator: {x.Type} - {y.Type}"); },
				(x,y)=>{ throw new NotSupportedException($"Not Supported operator: {x.Type} * {y.Type}"); },
				(x,y)=>{ throw new NotSupportedException($"Not Supported operator: {x.Type} / {y.Type}"); }
			},
			{	//Pointer.VT_BIN
				(x,y)=>{ return x + y.Value<byte[]>(); },
				(x,y)=>{ throw new NotSupportedException($"Not Supported operator: {x.Type} - {y.Type}"); },
				(x,y)=>{ throw new NotSupportedException($"Not Supported operator: {x.Type} * {y.Type}"); },
				(x,y)=>{ throw new NotSupportedException($"Not Supported operator: {x.Type} / {y.Type}"); }
			},
			{	//Pointer.VT_DATETIME
				(x,y)=>{ throw new NotSupportedException($"Not Supported operator: {x.Type} + {y.Type}"); },
				(x,y)=>{ return x - y.Value<DateTime>(); },
				(x,y)=>{ throw new NotSupportedException($"Not Supported operator: {x.Type} * {y.Type}"); },
				(x,y)=>{ throw new NotSupportedException($"Not Supported operator: {x.Type} / {y.Type}"); }
			},
			{	//Pointer.VT_TIMESPAN
				(x,y)=>{ return x + y.Value<TimeSpan>(); },
				(x,y)=>{ return x - y.Value<TimeSpan>(); },
				(x,y)=>{ throw new NotSupportedException($"Not Supported operator: {x.Type} * {y.Type}"); },
				(x,y)=>{ throw new NotSupportedException($"Not Supported operator: {x.Type} / {y.Type}"); }
			},
			{	//Pointer.VT_EU
				(x,y)=>{ return x + y.Value<EUValue>(); },
				(x,y)=>{ return x - y.Value<EUValue>(); },
				(x,y)=>{ return x * y.Value<EUValue>(); },
				(x,y)=>{ return x / y.Value<EUValue>(); }
			},
			{	//Pointer.VT_LIST
				(x,y)=>{ throw new NotSupportedException($"Not Supported operator: {x.Type} + {y.Type}"); },
				(x,y)=>{ throw new NotSupportedException($"Not Supported operator: {x.Type} - {y.Type}"); },
				(x,y)=>{ throw new NotSupportedException($"Not Supported operator: {x.Type} * {y.Type}"); },
				(x,y)=>{ throw new NotSupportedException($"Not Supported operator: {x.Type} / {y.Type}"); }
			},
			{	//Pointer.VT_MAP
				(x,y)=>{ throw new NotSupportedException($"Not Supported operator: {x.Type} + {y.Type}"); },
				(x,y)=>{ throw new NotSupportedException($"Not Supported operator: {x.Type} - {y.Type}"); },
				(x,y)=>{ throw new NotSupportedException($"Not Supported operator: {x.Type} * {y.Type}"); },
				(x,y)=>{ throw new NotSupportedException($"Not Supported operator: {x.Type} / {y.Type}"); }
			},
		};

		protected static Func<Pointer, dynamic, Pointer>[,] _arrPointerTypeOperators = new Func<Pointer, dynamic, Pointer>[(int)TypeID.PTI_COUNT, 4]
		{
			{	//Pointer.VT_BOOL
				(x, y) => { return (x as Pointer<bool>) + y; },
				(x, y) => { return (x as Pointer<bool>) - y; },
				(x, y) => { throw new NotSupportedException($"Not Supported operator: {x.Type} * {y.Type}"); },
				(x, y) => { throw new NotSupportedException($"Not Supported operator: {x.Type} / {y.Type}"); }
			},
			{	//Pointer.VT_SBYTE
				(x, y) => { return (x as Pointer<sbyte>) + y; },
				(x, y) => { return (x as Pointer<sbyte>) - y; },
				(x, y) => { return (x as Pointer<sbyte>) * y; },
				(x, y) => { return (x as Pointer<sbyte>) / y; }
			},
			{	//Pointer.VT_SHORT
				(x, y) => { return (x as Pointer<short>) + y; },
				(x, y) => { return (x as Pointer<short>) - y; },
				(x, y) => { return (x as Pointer<short>) * y; },
				(x, y) => { return (x as Pointer<short>) / y; }
			},
			{	//Pointer.VT_INT
				(x, y) => { return (x as Pointer<int>) + y; },
				(x, y) => { return (x as Pointer<int>) - y; },
				(x, y) => { return (x as Pointer<int>) * y; },
				(x, y) => { return (x as Pointer<int>) / y; }
			},
			{	//Pointer.VT_LONG
				(x, y) => { return (x as Pointer<long>) + y; },
				(x, y) => { return (x as Pointer<long>) - y; },
				(x, y) => { return (x as Pointer<long>) * y; },
				(x, y) => { return (x as Pointer<long>) / y; }
			},
			{	//Pointer.VT_BYTE
				(x, y) => { return (x as Pointer<byte>) + y; },
				(x, y) => { return (x as Pointer<byte>) - y; },
				(x, y) => { return (x as Pointer<byte>) * y; },
				(x, y) => { return (x as Pointer<byte>) / y; }
			},
			{	//Pointer.VT_USHORT
				(x, y) => { return (x as Pointer<ushort>) + y; },
				(x, y) => { return (x as Pointer<ushort>) - y; },
				(x, y) => { return (x as Pointer<ushort>) * y; },
				(x, y) => { return (x as Pointer<ushort>) / y; }
			},
			{	//Pointer.VT_UINT
				(x, y) => { return (x as Pointer<uint>) + y; },
				(x, y) => { return (x as Pointer<uint>) - y; },
				(x, y) => { return (x as Pointer<uint>) * y; },
				(x, y) => { return (x as Pointer<uint>) / y; }
			},
			{	//Pointer.VT_ULONG
				(x, y) => { return (x as Pointer<ulong>) + y; },
				(x, y) => { return (x as Pointer<ulong>) - y; },
				(x, y) => { return (x as Pointer<ulong>) * y; },
				(x, y) => { return (x as Pointer<ulong>) / y; }
			},
			{	//Pointer.VT_DECIMAL
				(x, y) => { return (x as Pointer<decimal>) + y; },
				(x, y) => { return (x as Pointer<decimal>) - y; },
				(x, y) => { return (x as Pointer<decimal>) * y; },
				(x, y) => { return (x as Pointer<decimal>) / y; }
			},
			{	//Pointer.VT_FLOAT
				(x, y) => { return (x as Pointer<float>) + y; },
				(x, y) => { return (x as Pointer<float>) - y; },
				(x, y) => { return (x as Pointer<float>) * y; },
				(x, y) => { return (x as Pointer<float>) / y; }
			},
			{	//Pointer.VT_DOUBLE
				(x, y) => { return (x as Pointer<double>) + y; },
				(x, y) => { return (x as Pointer<double>) - y; },
				(x, y) => { return (x as Pointer<double>) * y; },
				(x, y) => { return (x as Pointer<double>) / y; }
			},
			{	//Pointer.VT_STRING
				(x, y) => { return (x as Pointer<string>) + y; },
				(x, y) => { throw new NotSupportedException($"Not Supported operator: {x.Type} - {y.Type}"); },
				(x, y) => { throw new NotSupportedException($"Not Supported operator: {x.Type} * {y.Type}"); },
				(x, y) => { throw new NotSupportedException($"Not Supported operator: {x.Type} / {y.Type}"); }
			},
			{	//Pointer.VT_BIN
				(x, y) => { return (x as Pointer<byte[]>) + y; },
				(x, y) => { throw new NotSupportedException($"Not Supported operator: {x.Type} - {y.Type}"); },
				(x, y) => { throw new NotSupportedException($"Not Supported operator: {x.Type} * {y.Type}"); },
				(x, y) => { throw new NotSupportedException($"Not Supported operator: {x.Type} / {y.Type}"); }
			},
			{	//Pointer.VT_DATETIME
				(x, y) => { throw new NotSupportedException($"Not Supported operator: {x.Type} + {y.Type}"); },
				(x, y) => { return (x as Pointer<DateTime>) - y; },
				(x, y) => { throw new NotSupportedException($"Not Supported operator: {x.Type} * {y.Type}"); },
				(x, y) => { throw new NotSupportedException($"Not Supported operator: {x.Type} / {y.Type}"); }
			},
			{	//Pointer.VT_TIMESPAN
				(x, y) => { return (x as Pointer<TimeSpan>) + y; },
				(x, y) => { return (x as Pointer<TimeSpan>) - y; },
				(x, y) => { throw new NotSupportedException($"Not Supported operator: {x.Type} * {y.Type}"); },
				(x, y) => { throw new NotSupportedException($"Not Supported operator: {x.Type} / {y.Type}"); }
			},
			{	//Pointer.VT_EU
				(x, y) => { return (x as Pointer<EUValue>) + y; },
				(x, y) => { return (x as Pointer<EUValue>) - y; },
				(x, y) => { return (x as Pointer<EUValue>) * y; },
				(x, y) => { return (x as Pointer<EUValue>) / y; }
			},
			{	//Pointer.VT_LIST
				(x, y) => { throw new NotSupportedException($"Not Supported operator: {x.Type} + {y.Type}"); },
				(x, y) => { throw new NotSupportedException($"Not Supported operator: {x.Type} - {y.Type}"); },
				(x, y) => { throw new NotSupportedException($"Not Supported operator: {x.Type} * {y.Type}"); },
				(x, y) => { throw new NotSupportedException($"Not Supported operator: {x.Type} / {y.Type}"); }
			},
			{	//Pointer.VT_MAP
				(x, y) => { throw new NotSupportedException($"Not Supported operator: {x.Type} + {y.Type}"); },
				(x, y) => { throw new NotSupportedException($"Not Supported operator: {x.Type} - {y.Type}"); },
				(x, y) => { throw new NotSupportedException($"Not Supported operator: {x.Type} * {y.Type}"); },
				(x, y) => { throw new NotSupportedException($"Not Supported operator: {x.Type} / {y.Type}"); }
			},
		};

		protected static Func<Pointer, JObject, Pointer>[] _arrSetPointerValueJObjectOps = new Func<Pointer, JObject, Pointer>[(int)TypeID.PTI_COUNT]
		{
			(x, y) => { return (x as Pointer<bool>)!.SetValue(y.Value<bool>(Pointer.VAL)); },
			(x, y) => { return (x as Pointer<sbyte>)!.SetValue(y.Value<sbyte>(Pointer.VAL)); },
			(x, y) => { return (x as Pointer<short>)!.SetValue(y.Value<short>(Pointer.VAL)); },
			(x, y) => { return (x as Pointer<int>)!.SetValue(y.Value<int>(Pointer.VAL)); },
			(x, y) => { return (x as Pointer<long>)!.SetValue(y.Value<long>(Pointer.VAL)); },
			(x, y) => { return (x as Pointer<byte>)!.SetValue(y.Value<byte>(Pointer.VAL)); },
			(x, y) => { return (x as Pointer<ushort>)!.SetValue(y.Value<ushort>(Pointer.VAL)); },
			(x, y) => { return (x as Pointer<uint>)!.SetValue(y.Value<uint>(Pointer.VAL)); },
			(x, y) => { return (x as Pointer<ulong>)!.SetValue(y.Value<ulong>(Pointer.VAL)); },
			(x, y) => { return (x as Pointer<decimal>)!.SetValue(y.Value<decimal>(Pointer.VAL)); },
			(x, y) => { return (x as Pointer<float>)!.SetValue(y.Value<float>(Pointer.VAL)); },
			(x, y) => { return (x as Pointer<double>)!.SetValue(y.Value<double>(Pointer.VAL)); },
			(x, y) => { return (x as Pointer<string>)!.SetValue(y.Value<string>(Pointer.VAL)); },
			(x, y) => { return (x as Pointer<byte[]>)!.SetValue(y.Value<byte[]>(Pointer.VAL)); },
			(x, y) => { return (x as Pointer<DateTime>)!.SetValue(y.Value<DateTime>(Pointer.VAL)); },
			(x, y) => { return (x as Pointer<TimeSpan>)!.SetValue(y.Value<TimeSpan>(Pointer.VAL)); },
			(x, y) => { return (x as Pointer<EUValue>)!.SetValue(y.Value<EUValue>(Pointer.VAL)); },
			(x, y) => { throw new NotSupportedException($"Not support operator: SetValue<List>"); },
			(x, y) => { throw new NotSupportedException($"Not support operator: SetValue<List>"); },
		};

		protected static Func<Pointer, dynamic, Pointer>[] _arrSetPointerValueStringOps = new Func<Pointer, dynamic, Pointer>[(int)TypeID.PTI_COUNT]
		{
			(x, y) => { return (x as Pointer<bool>)!.SetValue(bool.Parse(y)); },
			(x, y) => { return (x as Pointer<sbyte>)!.SetValue(sbyte.Parse(y)); },
			(x, y) => { return (x as Pointer<short>)!.SetValue(short.Parse(y)); },
			(x, y) => { return (x as Pointer<int>)!.SetValue(int.Parse(y)); },
			(x, y) => { return (x as Pointer<long>)!.SetValue(long.Parse(y)); },
			(x, y) => { return (x as Pointer<byte>)!.SetValue(byte.Parse(y)); },
			(x, y) => { return (x as Pointer<ushort>)!.SetValue(ushort.Parse(y)); },
			(x, y) => { return (x as Pointer<uint>)!.SetValue(uint.Parse(y)); },
			(x, y) => { return (x as Pointer<ulong>)!.SetValue(ulong.Parse(y)); },
			(x, y) => { return (x as Pointer<decimal>)!.SetValue(decimal.Parse(y)); },
			(x, y) => { return (x as Pointer<float>)!.SetValue(float.Parse(y)); },
			(x, y) => { return (x as Pointer<double>)!.SetValue(double.Parse(y)); },
			(x, y) => { return (x as Pointer<string>)!.SetValue(y); },
			(x, y) => { var v = Convert.FromBase64String(y); return (x as Pointer<byte[]>)!.SetValue(v); },
			(x, y) => { return (x as Pointer<DateTime>)!.SetValue(DateTime.Parse(y)); },
			(x, y) => { return (x as Pointer<TimeSpan>)!.SetValue(TimeSpan.Parse(y)); },
			(x, y) => { return (x as Pointer<EUValue>)!.SetValue(EUValue.Parse(y)); },
			(x, y) => { throw new NotSupportedException($"Not support operator: SetValue<List>"); },
			(x, y) => { throw new NotSupportedException($"Not support operator: SetValue<List>"); },
		};

		protected static Func<Pointer, string>[] _arrToStringOps = new Func<Pointer, string>[(int)TypeID.PTI_COUNT]
		{
			(x) => { return (x as Pointer<bool>)!.ToString(); },
			(x) => { return (x as Pointer<sbyte>)!.ToString(); },
			(x) => { return (x as Pointer<short>)!.ToString(); },
			(x) => { return (x as Pointer<int>)!.ToString(); },
			(x) => { return (x as Pointer<long>)!.ToString(); },
			(x) => { return (x as Pointer<byte>)!.ToString(); },
			(x) => { return (x as Pointer<ushort>)!.ToString(); },
			(x) => { return (x as Pointer<uint>)!.ToString(); },
			(x) => { return (x as Pointer<ulong>)!.ToString(); },
			(x) => { return (x as Pointer<decimal>)!.ToString(); },
			(x) => { return (x as Pointer<float>)!.ToString(); },
			(x) => { return (x as Pointer<double>)!.ToString(); },
			(x) => { return (x as Pointer<string>)!.ToString(); },
			(x) => { return (x as Pointer<byte[]>)!.ToString(); },
			(x) => { return (x as Pointer<DateTime>)!.ToString(); },
			(x) => { return (x as Pointer<TimeSpan>)!.ToString(); },
			(x) => { return (x as Pointer<EUValue>)!.ToString(); },
			(x) => { throw new NotSupportedException($"Not support operator: <List>"); },
			(x) => { throw new NotSupportedException($"Not support operator: <List>"); },
		};

		#region Pointer op Pointer
		public static Pointer operator +(Pointer x, Pointer y)
		{
			return _arrTypeID2PointeTypeOp[(int)y.PointerTypeID, 0](x, y);
		}

		public static Pointer operator -(Pointer x, Pointer y)
		{
			return _arrTypeID2PointeTypeOp[(int)y.PointerTypeID, 1](x, y);
		}

		public static Pointer operator *(Pointer x, Pointer y)
		{
			return _arrTypeID2PointeTypeOp[(int)y.PointerTypeID, 2](x, y);
		}

		public static Pointer operator /(Pointer x, Pointer y)
		{
			return _arrTypeID2PointeTypeOp[(int)y.PointerTypeID, 3](x, y);
		}

		public static Pointer operator +(Pointer x, bool y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 0](x, y); }
		public static Pointer operator -(Pointer x, bool y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 0](x, y); }
		public static Pointer operator *(Pointer x, bool y) { throw new NotSupportedException($"Not Supported operator: {x.Type} - {y.GetType().ToString()}"); }
		public static Pointer operator /(Pointer x, bool y) { throw new NotSupportedException($"Not Supported operator: {x.Type} - {y.GetType().ToString()}"); }

		public static Pointer operator +(Pointer x, sbyte y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 0](x, y); }
		public static Pointer operator -(Pointer x, sbyte y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 1](x, y); }
		public static Pointer operator *(Pointer x, sbyte y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 2](x, y); }
		public static Pointer operator /(Pointer x, sbyte y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 3](x, y); }

		public static Pointer operator +(Pointer x, short y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 0](x, y); }
		public static Pointer operator -(Pointer x, short y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 1](x, y); }
		public static Pointer operator *(Pointer x, short y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 2](x, y); }
		public static Pointer operator /(Pointer x, short y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 3](x, y); }

		public static Pointer operator +(Pointer x, int y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 0](x, y); }
		public static Pointer operator -(Pointer x, int y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 1](x, y); }
		public static Pointer operator *(Pointer x, int y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 2](x, y); }
		public static Pointer operator /(Pointer x, int y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 3](x, y); }

		public static Pointer operator +(Pointer x, long y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 0](x, y); }
		public static Pointer operator -(Pointer x, long y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 1](x, y); }
		public static Pointer operator *(Pointer x, long y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 2](x, y); }
		public static Pointer operator /(Pointer x, long y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 3](x, y); }

		public static Pointer operator +(Pointer x, byte y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 0](x, y); }
		public static Pointer operator -(Pointer x, byte y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 1](x, y); }
		public static Pointer operator *(Pointer x, byte y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 2](x, y); }
		public static Pointer operator /(Pointer x, byte y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 3](x, y); }

		public static Pointer operator +(Pointer x, ushort y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 0](x, y); }
		public static Pointer operator -(Pointer x, ushort y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 1](x, y); }
		public static Pointer operator *(Pointer x, ushort y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 2](x, y); }
		public static Pointer operator /(Pointer x, ushort y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 3](x, y); }

		public static Pointer operator +(Pointer x, uint y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 0](x, y); }
		public static Pointer operator -(Pointer x, uint y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 1](x, y); }
		public static Pointer operator *(Pointer x, uint y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 2](x, y); }
		public static Pointer operator /(Pointer x, uint y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 3](x, y); }

		public static Pointer operator +(Pointer x, ulong y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 0](x, y); }
		public static Pointer operator -(Pointer x, ulong y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 1](x, y); }
		public static Pointer operator *(Pointer x, ulong y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 2](x, y); }
		public static Pointer operator /(Pointer x, ulong y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 3](x, y); }

		public static Pointer operator +(Pointer x, decimal y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 0](x, y); }
		public static Pointer operator -(Pointer x, decimal y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 1](x, y); }
		public static Pointer operator *(Pointer x, decimal y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 2](x, y); }
		public static Pointer operator /(Pointer x, decimal y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 3](x, y); }

		public static Pointer operator +(Pointer x, float y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 0](x, y); }
		public static Pointer operator -(Pointer x, float y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 1](x, y); }
		public static Pointer operator *(Pointer x, float y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 2](x, y); }
		public static Pointer operator /(Pointer x, float y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 3](x, y); }

		public static Pointer operator +(Pointer x, double y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 0](x, y); }
		public static Pointer operator -(Pointer x, double y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 1](x, y); }
		public static Pointer operator *(Pointer x, double y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 2](x, y); }
		public static Pointer operator /(Pointer x, double y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 3](x, y); }

		public static Pointer operator +(Pointer x, string y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 0](x, y); }
		public static Pointer operator -(Pointer x, string y) { throw new NotSupportedException($"Not Supported operator: {x.Type} - {y.GetType().ToString()}"); }
		public static Pointer operator *(Pointer x, string y) { throw new NotSupportedException($"Not Supported operator: {x.Type} * {y.GetType().ToString()}"); }
		public static Pointer operator /(Pointer x, string y) { throw new NotSupportedException($"Not Supported operator: {x.Type} / {y.GetType().ToString()}"); }

		public static Pointer operator +(Pointer x, byte[] y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 0](x, y); }
		public static Pointer operator -(Pointer x, byte[] y) { throw new NotSupportedException($"Not Supported operator: {x.Type} - {y.GetType().ToString()}"); }
		public static Pointer operator *(Pointer x, byte[] y) { throw new NotSupportedException($"Not Supported operator: {x.Type} * {y.GetType().ToString()}"); }
		public static Pointer operator /(Pointer x, byte[] y) { throw new NotSupportedException($"Not Supported operator: {x.Type} / {y.GetType().ToString()}"); }

		public static Pointer operator +(Pointer x, DateTime y) { throw new NotSupportedException($"Not Supported operator: {x.Type} + {y.GetType().ToString()}"); }
		public static Pointer operator -(Pointer x, DateTime y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 1](x, y); }
		public static Pointer operator *(Pointer x, DateTime y) { throw new NotSupportedException($"Not Supported operator: {x.Type} * {y.GetType().ToString()}"); }
		public static Pointer operator /(Pointer x, DateTime y) => throw new NotSupportedException($"Not Supported operator: {x.Type} / {y.GetType().ToString()}");

		public static Pointer operator +(Pointer x, TimeSpan y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 0](x, y); }
		public static Pointer operator -(Pointer x, TimeSpan y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 1](x, y); }
		public static Pointer operator *(Pointer x, TimeSpan y) { throw new NotSupportedException($"Not Supported operator: {x.Type} * {y.GetType().ToString()}"); }
		public static Pointer operator /(Pointer x, TimeSpan y) { throw new NotSupportedException($"Not Supported operator: {x.Type} / {y.GetType().ToString()}"); }

		public static Pointer operator +(Pointer x, EUValue y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 0](x, y); }
		public static Pointer operator -(Pointer x, EUValue y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 1](x, y); }
		public static Pointer operator *(Pointer x, EUValue y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 2](x, y); }
		public static Pointer operator /(Pointer x, EUValue y) { return _arrPointerTypeOperators[(int)x.PointerTypeID, 3](x, y); }

		//public static Pointer operator +(Pointer x, Object y) { return x + y; }
		//public static Pointer operator -(Pointer x, Object y) { return x - y; }
		//public static Pointer operator *(Pointer x, Object y) { return x * y; }
		//public static Pointer operator /(Pointer x, Object y) { return x / y; }

		//public static Pointer operator +(Pointer x, Object y) { return x + y; }
		//public static Pointer operator -(Pointer x, Object y) { return x - y; }
		//public static Pointer operator *(Pointer x, Object y) { return x * y; }
		//public static Pointer operator /(Pointer x, Object y) { return x / y; }
		#endregion

		/// <summary>
		/// return the Pid
		/// </summary>
		public string Pid
		{
			get; protected set;
		} = "";

		/// <summary>
		/// return the description
		/// </summary>
		public string Description
		{
			get; protected set;
		} = "";

		/// <summary>
		/// return the name
		/// </summary>
		public string Name
		{
			get; protected set;
		} = "";

		/// <summary>
		/// return the Attributes list of Pointer
		/// </summary>
		public Pointer.Attributes Attr
		{
			get; protected set;
		} = @default;

		public string Type
		{
			get; protected set;
		} = Pointer.VT_INT;

		/// <summary>
		/// Pointer's Monitoring State: true: any changing of pointer will be notified to call CellService.PointerUpdated event
		/// </summary>
		public bool MonitoringState { get; internal set; } = false;
	}

	public class Pointer<T> : Pointer
	{
		dynamic? _val = default(T);
		JObject? _joVal = null;
		JObject? _joHelper = null;

		public Pointer()
			: base()
		{
			PointerTypeID = _dctType2ID[typeof(T)];
			_joVal = new JObject();
			_val = InitializeValue();
		}

		public Pointer(string pid = "", string name = "", string desc = "", Pointer.Attributes attr = Pointer.Attributes.Default)
			: base(pid, name, desc, attr)
		{
			PointerTypeID = _dctType2ID[typeof(T)];
			_joVal = new JObject();
			_val = InitializeValue();
		}

		public Pointer(JObject joVal, string pid = "", string name = "", string desc = "", Pointer.Attributes attr = Pointer.Attributes.Default)
			: base(pid, name, desc, attr)
		{
			PointerTypeID = _dctType2ID[typeof(T)];
			_joVal = joVal;
			_val = InitializeValue(false);
		}

		public Pointer(JObject joVal, JObject joHelper, string pid = "", string name = "", string desc = "", Pointer.Attributes attr = Pointer.Attributes.Default)
			: base(pid, name, desc, attr)
		{
			PointerTypeID = _dctType2ID[typeof(T)];
			_joVal = joVal;
			_joHelper = joHelper;
			_val = InitializeValue(false);
		}

		private dynamic InitializeValue(bool blDef = true)
		{
			if (blDef == true)
			{
				return _dctPointerType2MakeDefValue[typeof(T)]();
			}
			else if (_joVal == null)
			{
				return _dctPointerType2MakeDefValue[typeof(T)]();
			}
			else if (!_joVal.ContainsKey(Pointer.VAL))
			{
				return _dctPointerType2MakeDefValue[typeof(T)]();
			}
			else
			{
				return _dctPointerType2MakeValue[typeof(T)](_joVal[Pointer.VAL]! as JToken);
			}

			throw new Exception($"Exception: unknow exception");
		}

		TypeID _PointerTypeID;

        public override event PointerPropertyChangedEventHandler? PointerPropertyChanged;
        public override event PointerPropertyChangingEventHandler? PointerPropertyChanging;

        protected virtual void OnPointerPropertyChanged(JProperty property)
		{
			if (this.PointerPropertyChanged != null)
				this.PointerPropertyChanged(this, new PointerPropertyChangedEventArgs(property));
		}

		protected virtual bool OnPointerPropertyChanging(JProperty jpProperty)
		{
			bool blRet = true;

			if (this.PointerPropertyChanging != null)
				blRet = this.PointerPropertyChanging(this, new PointerPropertyChangingEventArgs(jpProperty));

			return blRet;
		}

		protected override TypeID PointerTypeID
		{
			get { return _PointerTypeID; }
			set { _PointerTypeID = _dctType2ID[typeof(T)]; }
		}

		public override Pointer SetValue<T1>(T1 v)
		{
			if (_val != v)
			{
				JProperty property = new JProperty(Pointer.VAL, v);
				if (OnPointerPropertyChanging(property) == true)
				{
					_val = v!;
					OnPointerPropertyChanged(property);
				}
			}

			return this;
		}

		public override T1 Value<T1>()
		{
			return (T1)_val!;
		}
		public override string ToString()
		{
			_joVal![Pointer.VAL] = _val;
			return _joVal.ToString(Formatting.None);
		}
		public override JObject JValue => _joVal!;


		public static Pointer<T> operator !(Pointer<T> v)
		{
			if (v.PointerTypeID == TypeID.PTI_BOOL)
				v._val = !v._val;
			else
				throw new NotSupportedException($"Not Supported operator: !{v.Type}");

			return v;
		}

		#region Pointer operator +
		public static Pointer operator +(Pointer<T> x, bool v)
		{
			x.SetValue<bool>(x._val && v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator +(Pointer<T> x, sbyte v)
		{
			x.SetValue(x._val + v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator +(Pointer<T> x, short v)
		{
			x.SetValue(x._val + v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator +(Pointer<T> x, int v)
		{
			x.SetValue(x._val + v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator +(Pointer<T> x, long v)
		{
			x.SetValue(x._val + v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator +(Pointer<T> x, byte v)
		{
			x.SetValue(x._val + v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator +(Pointer<T> x, ushort v)
		{
			x.SetValue(x._val + v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator +(Pointer<T> x, uint v)
		{
			x.SetValue(x._val + v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator +(Pointer<T> x, ulong v)
		{
			x.SetValue(x._val + v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator +(Pointer<T> x, decimal v)
		{
			x.SetValue(x._val + v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator +(Pointer<T> x, float v)
		{
			x.SetValue(x._val + v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator +(Pointer<T> x, double v)
		{
			x.SetValue(x._val + v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator +(Pointer<T> x, string v)
		{
			x.SetValue(x._val + v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator +(Pointer<T> x, byte[] v)
		{
			if (x.PointerTypeID == TypeID.PTI_BIN)
				x.SetValue((x._val as byte[])!.Concat(v).ToArray());
			else
				throw new NotSupportedException($"Not Supported operator: {x.Type} + {v.GetType().ToString()}");

			return x;
		}
		public static Pointer operator +(Pointer<T> x, DateTime v)
		{
			throw new NotSupportedException($"Not Supported operator: {x.Type} + {v.GetType().ToString()}");
		}
		public static Pointer operator +(Pointer<T> x, TimeSpan v)
		{
			if (x.PointerTypeID == TypeID.PTI_DATETIME || x.PointerTypeID == TypeID.PTI_TIMESPAN)
			{
				x.SetValue(x._val + v);
			}
			else
				throw new NotSupportedException($"Not Supported operator: {x.Type} / {v.GetType().ToString()}");

			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator +(Pointer<T> x, EUValue v)
		{
			x.SetValue(x._val + v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		#endregion

		#region Pointer operator -
		public static Pointer operator -(Pointer<T> x, bool v)  // bool or operator
		{
			x.SetValue(x._val || v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator -(Pointer<T> x, sbyte v)
		{
			x.SetValue(x._val - v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator -(Pointer<T> x, short v)
		{
			x.SetValue(x._val - v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator -(Pointer<T> x, int v)
		{
			x.SetValue(x._val - v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator -(Pointer<T> x, long v)
		{
			x.SetValue(x._val - v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator -(Pointer<T> x, byte v)
		{
			x.SetValue(x._val - v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator -(Pointer<T> x, ushort v)
		{
			x.SetValue(x._val - v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator -(Pointer<T> x, uint v)
		{
			x.SetValue(x._val - v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator -(Pointer<T> x, ulong v)
		{
			x.SetValue(x._val - v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator -(Pointer<T> x, decimal v)
		{
			x.SetValue(x._val - v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator -(Pointer<T> x, float v)
		{
			x.SetValue(x._val - v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator -(Pointer<T> x, double v)
		{
			x.SetValue(x._val - v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator -(Pointer<T> x, string v)
		{
			x.SetValue(x._val - v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator -(Pointer<T> x, byte[] v)
		{
			x.SetValue(x._val - v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator -(Pointer<T> x, DateTime v)
		{
			x.SetValue(x._val - v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator -(Pointer<T> x, TimeSpan v)
		{
			x.SetValue(x._val - v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator -(Pointer<T> x, EUValue v)
		{
			x.SetValue(x._val - v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		#endregion

		#region Pointer operator *
		public static Pointer operator *(Pointer<T> x, bool v)
		{
			throw new NotSupportedException($"Not Supported operator: {x.Type} / {v.GetType().ToString()}");
		}
		public static Pointer operator *(Pointer<T> x, sbyte v)
		{
			x.SetValue(x._val * v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator *(Pointer<T> x, short v)
		{
			x.SetValue(x._val * v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator *(Pointer<T> x, int v)
		{
			x.SetValue(x._val * v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator *(Pointer<T> x, long v)
		{
			x.SetValue(x._val * v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator *(Pointer<T> x, byte v)
		{
			x.SetValue(x._val * v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator *(Pointer<T> x, ushort v)
		{
			x.SetValue(x._val * v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator *(Pointer<T> x, uint v)
		{
			x.SetValue(x._val * v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator *(Pointer<T> x, ulong v)
		{
			x.SetValue(x._val * v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator *(Pointer<T> x, decimal v)
		{
			x.SetValue(x._val * v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator *(Pointer<T> x, float v)
		{
			x.SetValue(x._val * v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator *(Pointer<T> x, double v)
		{
			x.SetValue(x._val * v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator *(Pointer<T> x, string v)
		{
			throw new NotSupportedException($"Not Supported operator: {x.Type} * {v.GetType().ToString()}");
		}
		public static Pointer operator *(Pointer<T> x, byte[] v)
		{
			throw new NotSupportedException($"Not Supported operator: {x.Type} * {v.GetType().ToString()}");
		}
		public static Pointer operator *(Pointer<T> x, DateTime v)
		{
			throw new NotSupportedException($"Not Supported operator: {x.Type} * {v.GetType().ToString()}");
		}
		public static Pointer operator *(Pointer<T> x, TimeSpan v)
		{
			throw new NotSupportedException($"Not Supported operator: {x.Type} * {v.GetType().ToString()}");
		}
		public static Pointer operator *(Pointer<T> x, EUValue v)
		{
			x.SetValue(x._val * v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		#endregion

		#region Pointer operator /
		public static Pointer operator /(Pointer<T> x, bool v)
		{
			throw new NotSupportedException($"Not Supported operator: {x.Type} / {v.GetType().ToString()}");
		}
		public static Pointer operator /(Pointer<T> x, sbyte v)
		{
			x.SetValue(x._val / v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator /(Pointer<T> x, short v)
		{
			x.SetValue(x._val / v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator /(Pointer<T> x, int v)
		{
			x.SetValue(x._val / v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator /(Pointer<T> x, long v)
		{
			x.SetValue(x._val / v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator /(Pointer<T> x, byte v)
		{
			x.SetValue(x._val / v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator /(Pointer<T> x, ushort v)
		{
			x.SetValue(x._val / v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator /(Pointer<T> x, uint v)
		{
			x.SetValue(x._val / v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator /(Pointer<T> x, ulong v)
		{
			x.SetValue(x._val / v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator /(Pointer<T> x, decimal v)
		{
			x.SetValue(x._val / v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator /(Pointer<T> x, float v)
		{
			x.SetValue(x._val / v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator /(Pointer<T> x, double v)
		{
			x.SetValue(x._val / v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator /(Pointer<T> x, string v)
		{
			x.SetValue(x._val / v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		public static Pointer operator /(Pointer<T> x, byte[] v)
		{
			throw new NotSupportedException($"Not Supported operator: {x.Type} / {v.GetType().ToString()}");
		}
		public static Pointer operator /(Pointer<T> x, DateTime v)
		{
			throw new NotSupportedException($"Not Supported operator: {x.Type} / {v.GetType().ToString()}");
		}
		public static Pointer operator /(Pointer<T> x, TimeSpan v)
		{
			throw new NotSupportedException($"Not Supported operator: {x.Type} / {v.GetType().ToString()}");
		}
		public static Pointer operator /(Pointer<T> x, EUValue v)
		{
			x.SetValue(x._val / v);
			//x._joVal[Pointer.VAL] = x._val;
			return x;
		}
		#endregion
	}
}
